package com.jn.erp.web.api.student.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.jn.erp.common.utils.DateUtils;
import com.jn.erp.common.utils.StringUtils;
import com.jn.erp.security.entity.SysUser;
import com.jn.erp.security.mapper.SysUserMapper;
import com.jn.erp.web.api.common.entity.TLabel;
import com.jn.erp.web.api.common.enums.ErrorEnum;
import com.jn.erp.web.api.common.mapper.TLabelMapper;
import com.jn.erp.web.api.course.entity.TCourse;
import com.jn.erp.web.api.course.entity.TCourseOrder;
import com.jn.erp.web.api.course.entity.TCourseOrderConfig;
import com.jn.erp.web.api.course.entity.dto.TCourseDto;
import com.jn.erp.web.api.course.entity.vo.TCourseVo;
import com.jn.erp.web.api.course.mapper.TCourseMapper;
import com.jn.erp.web.api.course.mapper.TCourseOrderConfigMapper;
import com.jn.erp.web.api.course.mapper.TCourseOrderMapper;
import com.jn.erp.web.api.course.task.TCourseOrderTask;
import com.jn.erp.web.api.student.entity.StudentClass;
import com.jn.erp.web.api.student.entity.TStudentClassRela;
import com.jn.erp.web.api.student.entity.dto.StudentClassDto;
import com.jn.erp.web.api.student.entity.dto.StudentClassListExcalDto;
import com.jn.erp.web.api.student.entity.dto.StudentListDto;
import com.jn.erp.web.api.student.entity.vo.StudentClassExcalVo;
import com.jn.erp.web.api.student.entity.vo.StudentClassVo;
import com.jn.erp.web.api.student.mapper.StudentClassMapper;
import com.jn.erp.web.api.student.service.StudentClassRelaService;
import com.jn.erp.web.api.student.service.StudentClassService;
import com.jn.erp.web.api.student.service.StudentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;

@Service
public class StudentClassServiceImpl extends ServiceImpl<StudentClassMapper, StudentClass> implements StudentClassService {
    @Autowired
    private TCourseMapper tCourseMapper;
    @Autowired
    private TLabelMapper tLabelMapper;
    @Autowired
    private SysUserMapper sysUserMapper;
    @Autowired
    private StudentClassRelaService studentClassRelaService;
    @Autowired
    private StudentService studentService;
    @Autowired
    private TCourseOrderMapper tCourseOrderMapper;
    @Autowired
    private TCourseOrderConfigMapper tCourseOrderConfigMapper;
    @Autowired
    private TCourseOrderTask tCourseOrderTask;

    @Override
    public String saveClass(StudentClassVo studentClassVo) {
        List<StudentClass> tCourses = baseMapper.selectList(new QueryWrapper<StudentClass>().eq("name", studentClassVo.getName()).eq("org_id",studentClassVo.getId()).eq("deleted", "0"));
        if(!CollectionUtils.isEmpty(tCourses)){
            return ErrorEnum.E101.getValue();
        }
        baseMapper.insert(studentClassVo);
        return ErrorEnum.S200.getValue();
    }

    @Override
    public void deleteClassStudent(List<Long> studentIds) {
        QueryWrapper<StudentClass> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("student_id", studentIds);
        this.baseMapper.delete(queryWrapper);
    }

    @Override
    public List<StudentClassDto> classList(StudentClassVo studentClassVo) {

        List<StudentClassDto> studentClassDtos = this.baseMapper.classList(studentClassVo);

        if (!Objects.isNull(studentClassVo.getIfSchedule())) {
            if (studentClassVo.getIfSchedule() == 0) {
                studentClassDtos = studentClassDtos.stream().filter(u -> u.getOrderNum() > 0).collect(Collectors.toList());
            } else {
                studentClassDtos = studentClassDtos.stream().filter(u -> u.getOrderNum() <= 0).collect(Collectors.toList());

            }
        }
        return studentClassDtos;
    }

    @Override
    public StudentClass getClassById(StudentClassVo studentClassVo) {
        StudentClass studentClass = this.baseMapper.selectById(studentClassVo.getId());
        TCourseVo tCourseVo = new TCourseVo();
        tCourseVo.setIdsStr(studentClass.getCourseId());
        List<TCourseDto> list = tCourseMapper.courseList(tCourseVo);
        long count = studentClassRelaService.count(new QueryWrapper<TStudentClassRela>().eq("deleted", "0").eq("class_id", studentClassVo.getId()));
        studentClass.setStudentCount(count);
        StringBuffer stringBuffer = new StringBuffer();
        if (!CollectionUtils.isEmpty(list)) {
            list.stream().forEach(u -> stringBuffer.append(u.getName()).append(","));
            if (stringBuffer.length() > 0) {
                stringBuffer.setLength(stringBuffer.length() - 1); // 移除最后一位字符
            }
        }
        studentClass.setCourseName(stringBuffer.toString());
        if (!Objects.isNull(studentClass.getClassType())) {
            TLabel tLabel = tLabelMapper.selectById(studentClass.getClassType());
            studentClass.setClassTypeName(tLabel.getName());
        }
        if (!Objects.isNull(studentClass.getTeacherId())) {
            SysUser temp = new SysUser(studentClass.getTeacherId(), studentClassVo.getOrgId());
            SysUser sysUser = sysUserMapper.selectNickByUserId(temp);
            studentClass.setTeacherName(sysUser.getName());
        }
        return studentClass;
    }

    @Override
    public String importList(List<StudentClassExcalVo> studentClassExcalVos, Long orgId, Long userId) {
        if (!CollectionUtils.isEmpty(studentClassExcalVos)) {
            List<StudentClass> studentClasses = Lists.transform(studentClassExcalVos, (u) -> {
                StudentClass studentClass = new StudentClass();
                studentClass.setName(u.getClassName());
                if (!StringUtils.isEmpty(u.getPlannedStudentCount())) {
                    studentClass.setPlannedStudentCount(Long.valueOf(u.getPlannedStudentCount()));
                }
                studentClass.setRemark(u.getRemark());
                studentClass.setClassHour(StringUtils.isEmpty(u.getClassHour()) ? 1 : Integer.parseInt(u.getClassHour()));
                StringBuffer stringBuffer = new StringBuffer();
                if (!StringUtils.isEmpty(u.getCourse1())) {
                    List<TCourse> tCourses = tCourseMapper.selectList(new QueryWrapper<TCourse>().eq("name", u.getCourse1()).eq("is_delete", "0"));
                    if (!CollectionUtils.isEmpty(tCourses)) {
                        TCourse tCourse = tCourses.get(0);
                        if (!Objects.isNull(tCourse)) {
                            stringBuffer.append(tCourse.getName()).append(",");
                        }
                    }

                }
                if (!StringUtils.isEmpty(u.getCourse2())) {
                    List<TCourse> tCourses = tCourseMapper.selectList(new QueryWrapper<TCourse>().eq("name", u.getCourse1()).eq("is_delete", "0"));
                    if (!CollectionUtils.isEmpty(tCourses)) {
                        TCourse tCourse = tCourses.get(0);
                        if (!Objects.isNull(tCourse)) {
                            stringBuffer.append(tCourse.getName()).append(",");
                        }
                    }

                }
                if (!StringUtils.isEmpty(u.getCourse3())) {
                    List<TCourse> tCourses = tCourseMapper.selectList(new QueryWrapper<TCourse>().eq("name", u.getCourse1()).eq("is_delete", "0"));
                    if (!CollectionUtils.isEmpty(tCourses)) {
                        TCourse tCourse = tCourses.get(0);
                        if (!Objects.isNull(tCourse)) {
                            stringBuffer.append(tCourse.getName()).append(",");
                        }
                    }

                }
                if (!StringUtils.isEmpty(u.getCourse4())) {
                    List<TCourse> tCourses = tCourseMapper.selectList(new QueryWrapper<TCourse>().eq("name", u.getCourse1()).eq("is_delete", "0"));
                    if (!CollectionUtils.isEmpty(tCourses)) {
                        TCourse tCourse = tCourses.get(0);
                        if (!Objects.isNull(tCourse)) {
                            stringBuffer.append(tCourse.getName()).append(",");
                        }
                    }

                }
                if (!StringUtils.isEmpty(u.getCourse5())) {
                    List<TCourse> tCourses = tCourseMapper.selectList(new QueryWrapper<TCourse>().eq("name", u.getCourse1()).eq("is_delete", "0"));
                    if (!CollectionUtils.isEmpty(tCourses)) {
                        TCourse tCourse = tCourses.get(0);
                        if (!Objects.isNull(tCourse)) {
                            stringBuffer.append(tCourse.getName()).append(",");
                        }
                    }

                }
                if (!StringUtils.isEmpty(u.getCourse6())) {
                    List<TCourse> tCourses = tCourseMapper.selectList(new QueryWrapper<TCourse>().eq("name", u.getCourse1()).eq("is_delete", "0"));
                    if (!CollectionUtils.isEmpty(tCourses)) {
                        TCourse tCourse = tCourses.get(0);
                        if (!Objects.isNull(tCourse)) {
                            stringBuffer.append(tCourse.getName()).append(",");
                        }
                    }

                }
                if (!StringUtils.isEmpty(u.getCourse7())) {
                    List<TCourse> tCourses = tCourseMapper.selectList(new QueryWrapper<TCourse>().eq("name", u.getCourse1()).eq("is_delete", "0"));
                    if (!CollectionUtils.isEmpty(tCourses)) {
                        TCourse tCourse = tCourses.get(0);
                        if (!Objects.isNull(tCourse)) {
                            stringBuffer.append(tCourse.getName()).append(",");
                        }
                    }

                }
                if (!StringUtils.isEmpty(u.getCourse8())) {
                    List<TCourse> tCourses = tCourseMapper.selectList(new QueryWrapper<TCourse>().eq("name", u.getCourse1()).eq("is_delete", "0"));
                    if (!CollectionUtils.isEmpty(tCourses)) {
                        TCourse tCourse = tCourses.get(0);
                        if (!Objects.isNull(tCourse)) {
                            stringBuffer.append(tCourse.getName()).append(",");
                        }
                    }

                }
                if (!StringUtils.isEmpty(u.getCourse9())) {
                    List<TCourse> tCourses = tCourseMapper.selectList(new QueryWrapper<TCourse>().eq("name", u.getCourse1()).eq("is_delete", "0"));
                    if (!CollectionUtils.isEmpty(tCourses)) {
                        TCourse tCourse = tCourses.get(0);
                        if (!Objects.isNull(tCourse)) {
                            stringBuffer.append(tCourse.getName()).append(",");
                        }
                    }

                }
                if (!StringUtils.isEmpty(u.getCourse10())) {
                    List<TCourse> tCourses = tCourseMapper.selectList(new QueryWrapper<TCourse>().eq("name", u.getCourse1()).eq("is_delete", "0"));
                    if (!CollectionUtils.isEmpty(tCourses)) {
                        TCourse tCourse = tCourses.get(0);
                        if (!Objects.isNull(tCourse)) {
                            stringBuffer.append(tCourse.getName()).append(",");
                        }
                    }

                }
                if (stringBuffer.length() > 0) {
                    stringBuffer.setLength(stringBuffer.length() - 1); // 移除最后一位字符
                }
                studentClass.setCourseId(stringBuffer.toString());
                if (!StringUtils.isEmpty(u.getExcess())) {
                    if (u.getExcess().contains("不")) {
                        studentClass.setExcess(1);
                    } else {
                        studentClass.setExcess(0);
                    }
                }
                if (!StringUtils.isEmpty(u.getClassType())) {
                    List<TLabel> tLabels = tLabelMapper.selectList(new QueryWrapper<TLabel>().eq("name", u.getClassType()).eq("lable_type", "class_type").eq("is_delete", "0"));
                    if (!CollectionUtils.isEmpty(tLabels)) {
                        TLabel tLabel = tLabels.get(0);
                        if (!Objects.isNull(tLabel)) {
                            studentClass.setClassType(tLabel.getId());
                        }
                    }
                }
                if (!StringUtils.isEmpty(u.getClassType())) {
                    List<TLabel> tLabels = tLabelMapper.selectList(new QueryWrapper<TLabel>().eq("name", u.getClassType()).eq("lable_type", "class_room").eq("is_delete", "0"));
                    if (!CollectionUtils.isEmpty(tLabels)) {
                        TLabel tLabel = tLabels.get(0);
                        if (!Objects.isNull(tLabel)) {
                            studentClass.setClassroomId(tLabel.getId());
                        }
                    }
                }
                if (!StringUtils.isEmpty(u.getTeacher())) {
                    String phone = u.getTeacher().substring(u.getTeacher().length() - 12, u.getTeacher().length() - 1);
                    List<SysUser> sysUsers = sysUserMapper.selectList(new QueryWrapper<SysUser>().eq("mobile", phone));
                    if (!CollectionUtils.isEmpty(sysUsers)) {
                        SysUser sysUser = sysUsers.get(0);
                        if (!Objects.isNull(sysUser)) {
                            studentClass.setTeacherId(sysUser.getId());
                        }
                    }
                }
                studentClass.setOrgId(orgId);
                studentClass.setCreator(userId);
                studentClass.setAddTime(LocalDateTime.now());
                studentClass.setDeleted(0);
                studentClass.setIsVip(1);
                return studentClass;
            });
            if (!CollectionUtils.isEmpty(studentClasses)) {
                baseMapper.insertBatch(studentClasses);
            }
        }
        return "S200";
    }

    @Override
    public List<StudentListDto> studentCourseList(StudentClassVo studentClassVo) {
        List<StudentListDto> studentListDtos = baseMapper.studentCourseList(studentClassVo);
        return studentListDtos;
    }

    @Override
    public List<StudentClassListExcalDto> exportClassList(StudentClassVo studentClassVo) {
        List<StudentClassListExcalDto> studentClassListExcalDtos = baseMapper.exportClassList(studentClassVo);
        return studentClassListExcalDtos;
    }

    @Override
    public String addStudentToClass(List<TStudentClassRela> tStudentClassRelas,Integer type) {
       if(type == 2){
           TStudentClassRela t = tStudentClassRelas.get(0);
           List<Long> classIds = tStudentClassRelas.stream().map(TStudentClassRela::getClassId).filter(u->!Objects.isNull(u)).collect(Collectors.toList());
           //校验是否已在要移至的班级存在
            List<TStudentClassRela> removeClass = studentClassRelaService.list(new QueryWrapper<TStudentClassRela>().eq("deleted", "0").eq("student_id", t.getStudentId()).eq("consume_course_id", t.getConsumeCourseId()).notIn( !CollectionUtils.isEmpty(classIds),"class_id",classIds));
            if(!CollectionUtils.isEmpty(removeClass)){
                removeClass.stream().forEach(x->{
                    x.setDeleted(1);
                    studentClassRelaService.updateById(x);
                    //学员修改班级时更新课次
                    TCourseOrder tCourseOrder = new TCourseOrder();
                    tCourseOrder.setUpdateUser(String.valueOf(x.getEditor()));
                    tCourseOrder.setUpdateDate(LocalDateTime.now());
                    tCourseOrder.setIsDelete("1");
                    int update = tCourseOrderMapper.update(tCourseOrder, new QueryWrapper<TCourseOrder>().eq("student_id", x.getStudentId()).eq("class_id", x.getClassId()).ge("DATE_FORMAT(class_date, '%Y-%m-%d' )", DateUtils.getDate()).eq("state", 1));

                });
            }
        }
       List<TStudentClassRela> saveList = new ArrayList<>();
        tStudentClassRelas.stream().forEach(u -> {
            u.setId(null);
            List<TStudentClassRela> list = studentClassRelaService.list(new QueryWrapper<TStudentClassRela>().eq("class_id", u.getClassId()).eq("student_id", u.getStudentId()).eq("deleted", 0));
            //非空并且课程id不一致
            if(!CollectionUtils.isEmpty(list)){
                if(!list.get(0).getConsumeCourseId().equals(u.getConsumeCourseId())){
                    throw new RuntimeException(ErrorEnum.E110.getName());
                }
            }else{
                saveList.add(u);
            }
        });
        if(!CollectionUtils.isEmpty(saveList)&&!Objects.isNull(saveList.get(0).getClassId())){
            boolean code = studentClassRelaService.saveBatch(saveList);
        }

        //开线程池，线程数量为要遍历的对象的长度
        ExecutorService executor = Executors.newFixedThreadPool(1);
        CompletableFuture completableFuture = CompletableFuture.runAsync(() -> {
            Date ss = new Date();
            tCourseOrderTask.createCourseOrder();
            Date ee = new Date();
            System.out.printf("创建排课记录执行时间：%d 毫秒.", (ee.getTime() - ss.getTime()));
        }, executor);
        return "S200";
    }

    @Override
    public List<StudentListDto> studentList(StudentClassVo studentClassVo) {
        List<StudentListDto> studentListDtos = baseMapper.studentList(studentClassVo);
        return studentListDtos;
    }

    @Override
    public String removeStudent(TStudentClassRela tStudentClassRela) {
        if (Objects.isNull(tStudentClassRela.getClassIdNew())) {
            tStudentClassRela.setDeleted(1);
            studentClassRelaService.updateById(tStudentClassRela);
            //学员修改班级时更新课次
            TCourseOrder tCourseOrder = new TCourseOrder();
            tCourseOrder.setUpdateUser(String.valueOf(tStudentClassRela.getEditor()));
            tCourseOrder.setUpdateDate(LocalDateTime.now());
            tCourseOrder.setIsDelete("1");
            int update = tCourseOrderMapper.update(tCourseOrder, new QueryWrapper<TCourseOrder>().eq("student_id", tStudentClassRela.getStudentId()).eq("class_id", tStudentClassRela.getClassId()).ge("DATE_FORMAT(class_date, '%Y-%m-%d' )", DateUtils.getDate()).eq("state", 1));
        } else {
            //校验是否已在要移至的班级存在
            List<TStudentClassRela> tStudentClassRelas = studentClassRelaService.list(new QueryWrapper<TStudentClassRela>().eq("deleted", "0").eq("student_id", tStudentClassRela.getStudentId()).eq("class_id", tStudentClassRela.getClassIdNew()));
            if (!CollectionUtils.isEmpty(tStudentClassRelas)) {
                return ErrorEnum.E102.getValue();
            } else {
                //学员修改班级时更新课次
                TCourseOrder tCourseOrder = new TCourseOrder();
                tCourseOrder.setUpdateUser(String.valueOf(tStudentClassRela.getEditor()));
                tCourseOrder.setUpdateDate(LocalDateTime.now());
                tCourseOrder.setIsDelete("1");
                int update = tCourseOrderMapper.update(tCourseOrder, new QueryWrapper<TCourseOrder>().eq("student_id", tStudentClassRela.getStudentId()).eq("class_id", tStudentClassRela.getClassId()).ge("DATE_FORMAT(class_date, '%Y-%m-%d' )", DateUtils.getDate()).eq("state", 1));
                TStudentClassRela byId = studentClassRelaService.getById(tStudentClassRela.getId());
                //先删除后添加
                tStudentClassRela.setDeleted(1);
                studentClassRelaService.updateById(tStudentClassRela);

                TStudentClassRela tscr = new TStudentClassRela(null,tStudentClassRela.getClassIdNew(),byId.getStudentId()
                        ,LocalDateTime.now(),tStudentClassRela.getEditor(),tStudentClassRela.getReason(),0,"转移至其他班-" + byId.getId()
                        ,byId.getConsumeCourseId(),byId.getOrgId(),null,null,null);
                studentClassRelaService.save(tscr);
                //开线程池，线程数量为要遍历的对象的长度
                ExecutorService executor = Executors.newFixedThreadPool(1);
                CompletableFuture completableFuture = CompletableFuture.runAsync(() -> {
                    Date ss = new Date();
                    tCourseOrderTask.createCourseOrder();
                    Date ee = new Date();
                    System.out.printf("创建排课记录执行时间：%d 毫秒.", (ee.getTime() - ss.getTime()));
                }, executor);
            }


        }
        return "S200";
    }

    @Override
    public String updateClass(StudentClassVo studentClassVo) {
        this.updateById(studentClassVo);
//        结业变历史学员
        if (!Objects.isNull(studentClassVo.getBeOver()) && 0 == studentClassVo.getBeOver()) {
            List<TStudentClassRela> list = studentClassRelaService.list(new QueryWrapper<TStudentClassRela>().eq("deleted", 0).eq("class_id", studentClassVo.getId()));
            if (!CollectionUtils.isEmpty(list)) {
                list.stream().forEach(u -> studentService.changeStage(u.getStudentId(), 5, true));
            }
            //将排课，人员，之后的课次进行删除
            TCourseOrderConfig tCourseOrderConfig = new TCourseOrderConfig();
            tCourseOrderConfig.setUpdateUser(studentClassVo.getEditor().toString());
            tCourseOrderConfig.setUpdateDate(LocalDateTime.now());
            tCourseOrderConfig.setIsDelete("1");
            tCourseOrderConfigMapper.update(tCourseOrderConfig, new QueryWrapper<TCourseOrderConfig>().eq("class_id", studentClassVo.getId()));
            TStudentClassRela tStudentClassRela = new TStudentClassRela();
            tStudentClassRela.setEditor(studentClassVo.getEditor());
            tStudentClassRela.setEditTime(LocalDateTime.now());
            tStudentClassRela.setDeleted(1);
            studentClassRelaService.update(tStudentClassRela, new QueryWrapper<TStudentClassRela>().eq("class_id", studentClassVo.getId()));
            TCourseOrder tCourseOrder = new TCourseOrder();
            tCourseOrder.setUpdateUser(studentClassVo.getEditor().toString());
            tCourseOrder.setUpdateDate(LocalDateTime.now());
            tCourseOrder.setIsDelete("1");
            //需添加当天大于等于开课时间
            tCourseOrderMapper.update(tCourseOrder, new QueryWrapper<TCourseOrder>().eq("class_id", studentClassVo.getId())
                    .ge("class_date", LocalDateTime.now()));
        }
        Boolean boo = this.updateById(studentClassVo);
        return "S200";
    }

    @Override
    public StudentClass classCourseList(StudentClass tClass) {
        StudentClass courseId = baseMapper.selectById(tClass.getId());
        String courseId1 = courseId.getCourseId();
        String[] split1 = courseId1.split(",");
       QueryWrapper<TCourse> wrapper = new QueryWrapper<>();
        wrapper.in(split1.length>0,"id",split1);
        wrapper.eq("1".equals(tClass.getOpen()),"org_id",tClass.getOrgId());
        List<TCourse> tCourses = tCourseMapper.selectList(wrapper);
        courseId.setCourseList(tCourses);
        return courseId;
    }
}